#include "CastlingAction.hpp"


CastlingAction::CastlingFunction* CastlingAction::cast_funcs[] = 
{	
	&CastlingAction::castling_queen_side,
	&CastlingAction::castling_king_side
};


CastlingAction::CastlingAction(Chess::Color color, CastlingAction::Type ctype_)
	: Action(color, CASTLING), ctype(ctype_)
{}


CastlingAction::~CastlingAction()
{}

void CastlingAction::execute()
{
	try
	{
		CastlingAction::CastlingFunction* func = 0;
		
		func = *CastlingAction::cast_funcs[this->ctype];
		
		func(this->color);
	}
	catch (Exception* e)
	{	throw e;	}
}

CastlingAction::Type 	CastlingAction::getCastlingType() const
{	return (ctype);		}

void CastlingAction::castling_queen_side(Chess::Color color)
{
	try
	{
		Chessboard* 	cboard = Chess::getInstance()->getChessboard();
		unsigned int	king_x = (color == Chess::WHITE) ? KING_WHITE_INIT_X : KING_BLACK_INIT_X;
		unsigned int	king_nx = (color == Chess::WHITE) ? (KING_WHITE_INIT_X - 2) : (KING_BLACK_INIT_X + 2);
		unsigned int	rook_nx = (color == Chess::WHITE) ? (king_nx + 1) : (king_nx - 1);
		unsigned int	rook_x = (color == Chess::WHITE) ? ROOK_INIT_0_X : ROOK_INIT_1_X;
		
		Piece*	rook = cboard->getCell(Position(rook_x, 0, color))->getPiece();
		Piece*	king = cboard->getCell(Position(king_x, 0, color))->getPiece();
		
		
		rook->getCell()->setPiece(0);
		king->getCell()->setPiece(0);
		
		cboard->getCell(Position(rook_nx, 0, color))->setPiece(rook);
		cboard->getCell(Position(king_nx, 0, color))->setPiece(king);
		
		rook->setCell(cboard->getCell(Position(rook_nx, 0, color)));
		king->setCell(cboard->getCell(Position(king_nx, 0, color)));
		
		rook->incrNbMovements();
		king->incrNbMovements();
		
	}
	catch (Exception*	e)
	{	throw e;	}
}

void CastlingAction::castling_king_side(Chess::Color color)
{
	try
	{	
		Chessboard* 	cboard = Chess::getInstance()->getChessboard();
		unsigned int	king_x = (color == Chess::WHITE) ? KING_WHITE_INIT_X : KING_BLACK_INIT_X;
		unsigned int	king_nx = (color == Chess::WHITE) ? (KING_WHITE_INIT_X + 2) : (KING_BLACK_INIT_X - 2);
		unsigned int	rook_nx = (color == Chess::WHITE) ? (king_nx - 1) : (king_nx + 1);
		unsigned int	rook_x = (color == Chess::WHITE) ? ROOK_INIT_1_X : ROOK_INIT_0_X;

		Piece*	rook = cboard->getCell(Position(rook_x, 0, color))->getPiece();
		Piece*	king = cboard->getCell(Position(king_x, 0, color))->getPiece();
		
		rook->getCell()->setPiece(0);
		king->getCell()->setPiece(0);
		
		cboard->getCell(Position(rook_nx, 0, color))->setPiece(rook);
		cboard->getCell(Position(king_nx, 0, color))->setPiece(king);
		
		rook->setCell(cboard->getCell(Position(rook_nx, 0, color)));
		king->setCell(cboard->getCell(Position(king_nx, 0, color)));

		rook->incrNbMovements();
		king->incrNbMovements();
	}
	catch (Exception*	e)
	{	throw e;	}
}
